#include "mainview.h"
#include "ui_mainview.h"
#include <QThread>
#include <QGraphicsLayout>
#include <QtCharts/QLegendMarker>

MainView::MainView(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainView)
{
    ui->setupUi(this);


    //初始化六个圆的状态
    ui->graphicsView->circle_position(10, 10, 1);
    ui->graphicsView->circle_position(100, 10, 1);
    ui->graphicsView->circle_position(200, 10, 1);
    ui->graphicsView->circle_position(10, 80, 1);
    ui->graphicsView->circle_position(100, 80, 1);
    ui->graphicsView->circle_position(200, 80, 1);
    circles = ui->graphicsView->getCircles(); // 实现访问私有成员


    // 定时器（用于刷新串口）
    ftimer = new QTimer(this);
    ftimer->stop();
    //初始化串口
    scanSerialPort();
    // 初始化波特率
    baud_rate();

    // 定时器功能实现
    ftimer->setInterval(1000);//设置定时周期，单位：ms
    connect(ftimer,SIGNAL(timeout()),this,SLOT(timer_1000ms()));
    ftimer->start();

    // 初始化串口工作线程
    initSerialWorker();
    // 初始化图表工作线程
    initChartWorker();


}

// 图表更新线程函数
void MainView::initChartWorker()
{
    // 创建横纵坐标轴并设置显示范围
    // 创建图表1
    setupChart(ui->chartView, m_chart, m_lineSeries, m_axisX, m_axisY, "一号传感器");


    // 创建图表2
    setupChart(ui->chartView_2, m_chart1, m_lineSeries1, m_axisX1, m_axisY1, "二号传感器");

    chartThread = new QThread;
    chartWorker = new ChartWorker();

    chartWorker->moveToThread(chartThread);
    chartThread->start();
    connect(chartWorker, &ChartWorker::updateChart, this, &MainView::updateLineSeriesData);



    chartWorker->start();  // 启动图表更新定时器
}

// 线程更新串口函数
void MainView::initSerialWorker()
{
    //connect(serialPort, &QSerialPort::readyRead, this, &SerialWorker::readData);

    //串口数据的获取
    serialport = new QSerialPort(this);

    connect(serialport,SIGNAL(readyRead()),this,SLOT(serialPortReadyRead()));
    workerThread = new QThread;
    worker = new SerialWorker();
    worker->moveToThread(workerThread);

    // 初始化串口并将其传递给worker
    serialPortInit();
    worker->start(serialport);

    // 将worker的信号与MainView的槽连接
    //connect(worker, &SerialWorker::dataReceived, this, &MainView::onDataReceived);
    connect(this, &MainView::dataReceived, this, &MainView::onDataReceived);
//  判断是否是异常关闭
    connect(this, &MainView::btn_static,worker,&SerialWorker::updateBtnOnOff);


    // 启动工作线程
    workerThread->start();
}


//接收正常字符串数据
void MainView::serialPortReadyRead()
{
    // 暂时接收所有的串口数据
    QByteArray temp = serialport->readAll();
    buffer.append(temp);
    // 接受力传感的字节数组
    QByteArray group;

    // 假设帧头为6个0字节
    const QByteArray frameHeader(6, 0x00);

    // 使用一个while循环来处理所有完整的数据帧
    while (buffer.size() >= 6) {
        if (buffer.startsWith(frameHeader)) {
            // 帧头后面的数据
            int totalLength = 6 + (9 * 6) + (9 * 4);
            if (buffer.size() >= totalLength) {

                buffer.remove(0, 6); // 移除帧头

                // 解析9组 (6字节) 数据
                for (int i = 0; i < 9; ++i) {
                    group = buffer.mid(i * 6, 6);

                    short x = (static_cast<short>(static_cast<uint8_t>(group[0]))) | static_cast<short>(static_cast<uint8_t>(group[1]) << 8);
                    short y = (static_cast<short>(static_cast<uint8_t>(group[2]))) | static_cast<short>(static_cast<uint8_t>(group[3]) << 8);
                    short z = (static_cast<short>(static_cast<uint8_t>(group[4]))) | static_cast<short>(static_cast<uint8_t>(group[5]) << 8);
                    QString groupStr = QString("Group %1: X=%2, Y=%3, Z=%4").arg(i + 1).arg(x).arg(y).arg(z);
                    //ui->textEdit_rx->append(groupStr);
                    emit dataReceived(groupStr);

                    switch (i)
                    {
                    case 0:
                       y_list0.append(y);

                       if(y_list0.length() > 10) {
                           y_list0.removeFirst();
                       }

                        break;
                    case 1:

                        break;
                    case 2:
                        break;
                    case 3:
                        break;
                    case 4:
                        break;
                    case 5:
                        break;
                    case 6:
                        break;
                    case 7:
                        break;
                    case 8:
                        break;
                    case 9:
                        break;
                    }

                }


                buffer.remove(0, 9 * 6); // 移除9组数据

                // 解析9个温度值 (4字节)
                for (int i = 0; i < 9; ++i) {
                    QByteArray tempData = buffer.mid(i * 4, 4);
                    float temperature;
                    memcpy(&temperature, tempData.data(), sizeof(float));
                    QString tempStr = QString("Temperature %1: %2").arg(i + 1).arg(temperature);
                    //ui->textEdit_rx->append(tempStr);
                    emit dataReceived(tempStr);
                }

                buffer.remove(0, 9 * 4); // 移除9个温度值

                // 处理完一帧，继续处理下一帧
            } else {
                break; // 等待更多数据
            }
        } else {
            // 如果没有帧头，移除无效数据
            buffer.remove(0, 1);
        }
    }
}

// 添加一个槽函数来处理接收到的数据
void MainView::onDataReceived(const QString &data)
{
//    static int i = 0;

//    qDebug()<<"数据打印中："<<i<<" 次";
//    i++;
    ui->textEdit_rx->append(data);
    if (ui->textEdit_rx->document()->blockCount() > 2 * maxLines)
        {
            QTextCursor cursor(ui->textEdit_rx->document());
            cursor.movePosition(QTextCursor::Start); // 移动到文档的开始
            for (int i = 0; i < maxLines; ++i)
            {
                cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
            }
            cursor.removeSelectedText();
        }
}

void MainView::updateLineSeriesData()
{
    static int i = 0;

    qDebug()<<"定时器槽函数已经触发："<<i<<" 次";
    i++;
//    if(btn_on_off == 1)
//        //强制处理
//    {
//        serialPortInit();
//    }
    // 更新 case 0 对应的图表
        if (!this->y_list0.isEmpty()) {
            QList<QPointF> points0;
            for (int j = 0; j < this->y_list0.length(); j++) {
                points0.append(QPointF(j, this->y_list0.at(j)));
            }
            if (this->y_list0.length() < 10) {
                m_lineSeries->append(this->y_list0.length() - 1, this->y_list0.last());
            } else {
                m_lineSeries->replace(points0);
            }

            // 更新Y轴范围
            if (!points0.isEmpty()) {
                qreal minY = points0.first().y();
                qreal maxY = points0.first().y();
                for (const QPointF &point : points0) {
                    if (point.y() < minY) minY = point.y();
                    if (point.y() > maxY) maxY = point.y();
                }
                m_axisY->setRange(minY - 10, maxY + 10);
            }
        }

}
// 图表创建函数
void MainView::setupChart(QChartView *chartView, QChart *&chart, QLineSeries *&lineSeries, QValueAxis *&axisX, QValueAxis *&axisY, const QString &sensorName)
{
    axisX = new QValueAxis();
    axisY = new QValueAxis();
    axisX->setRange(0, AXIS_MAX_X);
    axisX->setTickCount(10);
    axisY->setRange(AXIS_MIN_Y, AXIS_MAX_Y);

    // 设置坐标轴线的颜色为绿色
    axisX->setLinePenColor(Qt::green);
    axisY->setLinePenColor(Qt::green);

    // 设置坐标轴标签的颜色为绿色
    axisX->setLabelsColor(Qt::green);
    axisY->setLabelsColor(Qt::green);

    // 隐藏 X 轴和 Y 轴的网格线
    axisX->setGridLineVisible(false);
    axisY->setGridLineVisible(false);

    lineSeries = new QLineSeries();
    lineSeries->setPointsVisible(true);
    lineSeries->setName(sensorName);
    // 设置线的颜色为绿色
    lineSeries->setColor(Qt::green);

    chart = new QChart();
    chart->addAxis(axisY, Qt::AlignLeft);
    chart->addAxis(axisX, Qt::AlignBottom);
    chart->addSeries(lineSeries);
    chart->setAnimationOptions(QChart::SeriesAnimations);

    // 设置背景为黑色
    chart->setBackgroundBrush(QBrush(Qt::black));

    // 使背景区域没有圆角
    chart->setBackgroundRoundness(0);

    // 设置内边界边距
    chart->setMargins(QMargins(0, 0, 0, 0));

    // 设置外边界边距
    chart->layout()->setContentsMargins(0, 0, 0, 0);

    lineSeries->attachAxis(axisX);
    lineSeries->attachAxis(axisY);

    chartView->setChart(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    chartView->setRubberBand(QChartView::RectangleRubberBand);

    // 获取图表的图例
    QLegend *legend = chart->legend();
    if (legend) {
        // 获取图例项
        QList<QLegendMarker *> markers = legend->markers(lineSeries);
        if (!markers.isEmpty()) {
            QLegendMarker *marker = markers.first();

            // 设置图例项的字体颜色为绿色
            marker->setLabelBrush(QBrush(Qt::green));  // 这里设置标签的颜色
        }
    }


}
// 查询串口
void MainView::scanSerialPort()
{
    // 查询可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        {
            // 添加串口到下拉菜单
            ui->cbx_setPortName->addItem(info.portName());
        }
        qDebug()<<"正在使用的串口："<<ui->cbx_setPortName->currentText();
    }
}

// 波特率设置
void MainView::baud_rate()
{
    // 添加串口到下拉菜单
    //ui->cbx_setBaudRate->addItem("9600");
    ui->cbx_setBaudRate->addItem("115200");
}

// 控制串口
void MainView::serialPortInit()
{
    serialport->setPortName(ui->cbx_setPortName->currentText());
    qDebug()<<"串口名称："<<serialport->portName();



    if (!serialport->open(QIODevice::ReadWrite))
       {
            qDebug()<<"错误，串口无法打开，可能被占用！";
            QMessageBox::about(this,"错误","串口无法打开，可能被占用！");
            serialport->close();
            return ;
       }

        //波特率
        serialport->setBaudRate(ui->cbx_setBaudRate->currentText().toInt());
        //serialport->setBaudRate(115200);
        qDebug()<<"波特率:"<<ui->cbx_setBaudRate->currentText().toInt();

        //停止位(一个停止位）
        serialport->setStopBits(QSerialPort::OneStop);
        qDebug()<<"停止位:"<<serialport->stopBits();

        //数据位(8个数据位)
        serialport->setDataBits(QSerialPort::Data8);

        //奇偶位(没有校验位)
        serialport->setParity(QSerialPort::NoParity);
        qDebug()<<"奇偶位:"<<serialport->parity();

        // 没有硬件控制流
        serialport->setFlowControl(QSerialPort::NoFlowControl) ;
}
MainView::~MainView()
{
    // 确保线程在退出前正确终止
    workerThread->quit();
    workerThread->wait();

    // 确保关闭图表线程
    chartThread->quit();
    chartThread->wait();
    // 关闭串口
    serialport->close();
    delete ui;
}


// 打开串口
void MainView::on_btn_serial_clicked()
{
    if (btn_on_off == 0)
         {

             ui->cbx_setPortName->setEnabled(false);
             ui->cbx_setBaudRate->setEnabled(false);
             ui->btn_serial->setText("暂停");
             // 关闭串口
             serialport->close();
             qDebug()<<"启动";
             serialPortInit();

         }

    if (btn_on_off == 1)
        {

            serialport->close();
            ui->cbx_setPortName->setEnabled(true);
            ui->cbx_setBaudRate->setEnabled(true);

            ui->btn_serial->setText("启动");
        }
    // 反转串口按钮的状态
    btn_on_off = !btn_on_off;
    emit btn_static(btn_on_off);
}

// 定时500ms刷新串口状态(端口自己关闭了)
void MainView::timer_1000ms()
{
    if (btn_on_off == 0)//判断串口处于未打开状态
    {
        if(btn_on_off == 1)
            //强制处理
        {
            serialPortInit();
        }
        else
        {
            choose_index = ui->cbx_setPortName->currentIndex();
            reflash_com();
        }

    }
   // qDebug()<<"试错";
}


// 定时器刷新串口状态
void MainView::reflash_com()
{

    ui->cbx_setPortName->clear();//清除选择串口下拉栏添加的所有项目
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        {
            ui->cbx_setPortName->addItem(info.portName());
        }
    }
    ui->cbx_setPortName->setCurrentIndex(choose_index);
    qDebug()<<"choose_index:"<<choose_index;
}



// 16进制和utf8互转
void MainView::on_btn_hex_clicked()
{
    if(!clr_state)
    {
        ui->btn_hex->setText("HEX");
        clr_state = 1;
    }
    else
    {
        ui->btn_hex->setText("UTF-8");
        clr_state = 0;
    }
}

// 清除串口数据
void MainView::on_btn_clr_clicked()
{
    ui->textEdit_rx->clear();
}
